#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>

// ======================== 数据结构定义 ========================

typedef enum {
    UNIT_INACTIVE,      // 未激活
    UNIT_ACTIVATING,    // 激活中
    UNIT_ACTIVE,        // 已激活
    UNIT_DEACTIVATING,  // 停用中
    UNIT_FAILED         // 失败
} UnitState;

typedef enum {
    UNIT_SERVICE,      // 服务单元
    UNIT_TARGET,       // 目标单元
    UNIT_SOCKET        // 套接字单元
} UnitType;

typedef struct Unit {
    char* name;               // 单元名称
    UnitType type;            // 单元类型
    UnitState state;          // 当前状态
    
    // 依赖关系
    struct Unit** dependencies;   // 依赖项
    int dependency_count;         // 依赖数量
    
    // 反向依赖
    struct Unit** reverse_deps;   // 哪些单元依赖我
    int reverse_dep_count;        // 反向依赖数量
    
    // 拓扑排序相关
    int in_degree;           // 入度（启动时需要满足的依赖数）
    int out_degree;          // 出度（多少单元依赖我）
    
    // 指定wants单元
    struct Unit** wants_units;   // .wants目录中的单元
    int wants_count;             // wants单元数量
} Unit;

typedef struct {
    Unit** units;            // 单元指针数组
    int count;               // 单元数量
    int capacity;            // 数组容量
} UnitRegistry;

// ======================== 全局注册表 ========================

UnitRegistry unit_registry = {NULL, 0, 0};

// ======================== 单元管理函数 ========================

// 创建新单元
Unit* unit_create(const char* name, UnitType type) {
    Unit* unit = malloc(sizeof(Unit));
    unit->name = strdup(name);
    unit->type = type;
    unit->state = UNIT_INACTIVE;
    unit->dependencies = NULL;
    unit->dependency_count = 0;
    unit->reverse_deps = NULL;
    unit->reverse_dep_count = 0;
    unit->in_degree = 0;
    unit->out_degree = 0;
    unit->wants_units = NULL;
    unit->wants_count = 0;
    
    // 添加到注册表
    if (unit_registry.count >= unit_registry.capacity) {
        int new_capacity = unit_registry.capacity == 0 ? 10 : unit_registry.capacity * 2;
        unit_registry.units = realloc(unit_registry.units, new_capacity * sizeof(Unit*));
        unit_registry.capacity = new_capacity;
    }
    unit_registry.units[unit_registry.count++] = unit;
    
    return unit;
}

// 添加依赖关系
void unit_add_dependency(Unit* source, Unit* target) {
    // 添加源到目标的依赖
    source->dependencies = realloc(source->dependencies, 
                                  (source->dependency_count + 1) * sizeof(Unit*));
    source->dependencies[source->dependency_count++] = target;
    
    // 添加目标的反向依赖
    target->reverse_deps = realloc(target->reverse_deps, 
                                 (target->reverse_dep_count + 1) * sizeof(Unit*));
    target->reverse_deps[target->reverse_dep_count++] = source;
}

// 添加wants单元
void unit_add_wants(Unit* target, Unit* service) {
    target->wants_units = realloc(target->wants_units, 
                                (target->wants_count + 1) * sizeof(Unit*));
    target->wants_units[target->wants_count++] = service;
    
    // 同时添加为依赖关系
    unit_add_dependency(target, service);
}

// 查找单元
Unit* find_unit(const char* name) {
    for (int i = 0; i < unit_registry.count; i++) {
        if (strcmp(unit_registry.units[i]->name, name) == 0) {
            return unit_registry.units[i];
        }
    }
    return NULL;
}

// ======================== 拓扑排序 ========================

// 计算入度和出度
void calculate_degrees(Unit* unit) {
    unit->in_degree = 0;
    unit->out_degree = 0;
    
    // 计算入度
    for (int i = 0; i < unit->dependency_count; i++) {
        unit->in_degree++;
    }
    
    // 计算出度
    unit->out_degree = unit->reverse_dep_count;
}

// 拓扑排序（Kahn算法）
Unit** topological_sort(Unit** units, int count, int* sorted_count) {
    // 初始化入度
    for (int i = 0; i < count; i++) {
        calculate_degrees(units[i]);
    }
    
    // 创建队列
    Unit** queue = malloc(count * sizeof(Unit*));
    int front = 0, rear = 0;
    *sorted_count = 0;
    
    // 将所有入度为0的节点加入队列
    for (int i = 0; i < count; i++) {
        if (units[i]->in_degree == 0) {
            queue[rear++] = units[i];
        }
    }
    
    // 存储排序结果
    Unit** sorted = malloc(count * sizeof(Unit*));
    
    // 处理队列
    while (front < rear) {
        Unit* current = queue[front++];
        sorted[(*sorted_count)++] = current;
        
        // 减少所有依赖项的入度
        for (int i = 0; i < current->reverse_dep_count; i++) {
            Unit* dependent = current->reverse_deps[i];
            dependent->in_degree--;
            
            // 如果入度变为0，加入队列
            if (dependent->in_degree == 0) {
                queue[rear++] = dependent;
            }
        }
    }
    
    free(queue);
    return sorted;
}


// 创建启动事务
Unit** create_start_transaction(Unit* target, int* unit_count) {
    // 收集所有需要启动的单元
    int max_units = 100;
    Unit** all_units = malloc(max_units * sizeof(Unit*));
    int count = 0;
    
    // 添加目标本身
    all_units[count++] = target;
    
    // 添加wants目录中的服务
    for (int i = 0; i < target->wants_count; i++) {
        all_units[count++] = target->wants_units[i];
    }
    
    // 添加其他依赖
    for (int i = 0; i < target->dependency_count; i++) {
        if (count >= max_units) {
            max_units *= 2;
            all_units = realloc(all_units, max_units * sizeof(Unit*));
        }
        all_units[count++] = target->dependencies[i];
    }
    
    // 拓扑排序
    int sorted_count;
    Unit** sorted_units = topological_sort(all_units, count, &sorted_count);
    
    free(all_units);
    
    *unit_count = sorted_count;
    return sorted_units;
}


// 执行启动事务
void execute_start_transaction(Unit** units, int count) {
    for (int i = 0; i < count; i++) {
        Unit* unit = units[i];
        
        // 跳过目标单元本身（只启动服务）
        if (unit->type != UNIT_SERVICE) continue;
        
        // 打印starting service
        printf("[....] Starting %s\n", unit->name);
        unit->state = UNIT_ACTIVATING;
        
        // 模拟启动过程
        struct timespec start, current;
        clock_gettime(CLOCK_MONOTONIC, &start);
        
        // 模拟启动延迟
        for (int j = 0; j < 3; j++) {
            usleep(300000); // 300ms 延迟
            printf(".");
            fflush(stdout);
        }
        
        // 计算启动时间
        clock_gettime(CLOCK_MONOTONIC, &current);
        double elapsed = (current.tv_sec - start.tv_sec) + 
                        (current.tv_nsec - start.tv_nsec) / 1e9;
        
        // 模拟启动成功
        unit->state = UNIT_ACTIVE;
        printf(" \033[1;32mOK\033[0m (%.3fs)\n", elapsed);
        printf("[  \033[1;32mOK\033[0m  ] Started %s\n", unit->name);
    }
}


// 启动一个target及其所有依赖
void start_target(Unit* target) {
    // 打印reaching target
    printf("[....] Reaching target %s\n", target->name);
    
    // 获取所有需要启动的单元
    int unit_count = 0;
    Unit** units_to_start = create_start_transaction(target, &unit_count);
    
    // 执行启动事务
    execute_start_transaction(units_to_start, unit_count);
    
    // 打印reached target
    printf("[  \033[1;32mOK\033[0m  ] Reached target %s\n\n", target->name);
    
    free(units_to_start);
}

// ======================== 启动过程模拟 ========================

// 模拟systemd启动过程
void simulate_systemd_boot() {
    printf("\n=== Simulating Systemd Boot Process ===\n\n");
    
    // 创建基本target
    Unit* sysinit = unit_create("sysinit.target", UNIT_TARGET);
    Unit* basic = unit_create("basic.target", UNIT_TARGET);
    Unit* multi_user = unit_create("multi-user.target", UNIT_TARGET);
    Unit* graphical = unit_create("graphical.target", UNIT_TARGET);
    
    // 创建系统服务
    Unit* udev = unit_create("systemd-udevd.service", UNIT_SERVICE);
    Unit* journal = unit_create("systemd-journald.service", UNIT_SERVICE);
    Unit* network = unit_create("network.service", UNIT_SERVICE);
    Unit* dbus = unit_create("dbus.service", UNIT_SERVICE);
    Unit* getty = unit_create("getty@tty1.service", UNIT_SERVICE);
    Unit* display = unit_create("display-manager.service", UNIT_SERVICE);
    
    // 设置依赖关系
    unit_add_dependency(basic, sysinit);
    unit_add_dependency(multi_user, basic);
    unit_add_dependency(graphical, multi_user);
    
    // 设置sysinit.target的服务
    unit_add_dependency(sysinit, udev);
    unit_add_dependency(sysinit, journal);
    
    // 设置basic.target的服务
    unit_add_dependency(basic, network);
    
    // 设置multi-user.target的wants服务
    unit_add_wants(multi_user, dbus);
    unit_add_wants(multi_user, getty);
    
    // 设置graphical.target的wants服务
    unit_add_wants(graphical, display);
    
    // 启动流程
    start_target(sysinit);
    start_target(basic);
    start_target(multi_user);
    start_target(graphical);
}

// 打印单元状态
void print_system_status() {
    printf("\n=== System Status ===\n");
    printf("%-30s %-12s %s\n", "UNIT", "STATE", "TYPE");
    for (int i = 0; i < unit_registry.count; i++) {
        Unit* unit = unit_registry.units[i];
        
        const char* state_str = "UNKNOWN";
        switch (unit->state) {
            case UNIT_INACTIVE: state_str = "INACTIVE"; break;
            case UNIT_ACTIVATING: state_str = "ACTIVATING"; break;
            case UNIT_ACTIVE: state_str = "ACTIVE"; break;
            case UNIT_DEACTIVATING: state_str = "DEACTIVATING"; break;
            case UNIT_FAILED: state_str = "FAILED"; break;
        }
        
        const char* type_str = "UNKNOWN";
        switch (unit->type) {
            case UNIT_SERVICE: type_str = "SERVICE"; break;
            case UNIT_TARGET: type_str = "TARGET"; break;
            case UNIT_SOCKET: type_str = "SOCKET"; break;
        }
        
        printf("%-30s %-12s %s\n", unit->name, state_str, type_str);
    }
    printf("\n");
}

// ======================== 清理函数 ========================

void cleanup() {
    for (int i = 0; i < unit_registry.count; i++) {
        Unit* unit = unit_registry.units[i];
        free(unit->name);
        if (unit->dependencies) free(unit->dependencies);
        if (unit->reverse_deps) free(unit->reverse_deps);
        if (unit->wants_units) free(unit->wants_units);
        free(unit);
    }
    free(unit_registry.units);
}

// ======================== 主函数 ========================

int main() {
    // 模拟systemd启动过程
    simulate_systemd_boot();
    
    // 打印系统状态
    print_system_status();
    
    // 清理
    cleanup();
    
    return 0;
}